﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BDAlertorApp.Protocol;
using BDAlertorApp.Util;


namespace BDAlertorApp.Service.impl
{
    /// <summary>
    /// 串口监听服务
    /// </summary>
    class SerialPortConnectService
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger("SerialPortConnectService");

        private static SerialPortConnectService instance = new SerialPortConnectService();

        public static SerialPortConnectService GetInstance()
        {

            return instance;
        }

        /// <summary>
        /// 连接状态
        /// </summary>
        public ConnectionStatus ConnectionStatus = ConnectionStatus.Disconnected;

        /// <summary>
        /// 串口对象
        /// </summary>
        SerialPort serialPort = null;

        /// <summary>
        /// 数据解析服务
        /// </summary>
        public DataPacketProcessService dataPacketProcessService = DataPacketProcessService.GetInstance();


        private SerialPortConnectService()
        {
            logger.Info("串口监听服务开启");
            serialPort = new SerialPort();

            //设置参数
            serialPort.DataBits = 8; //每个字节的标准数据位长度
            serialPort.StopBits = StopBits.One; //设置每个字节的标准停止位数
            serialPort.Parity = Parity.None; //设置奇偶校验检查协议
            serialPort.ReadTimeout = 3000; //单位毫秒
            serialPort.WriteTimeout = 3000; //单位毫秒
            serialPort.ReadBufferSize = 128;//
            //串口控件成员变量，字面意思为接收字节阀值，
            //串口对象在收到这样长度的数据之后会触发事件处理函数
            //一般都设为1
            serialPort.ReceivedBytesThreshold = 1;
            //            serialPort.WriteBufferSize = m_writeBufferSize;
            serialPort.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);
            
        }

        public bool Start()
        {
            try
            {
                serialPort.PortName = GlobalVariable.SerialPortName; //通信端口
                serialPort.BaudRate = GlobalVariable.SerialPortBaudRate; //串行波特率

                serialPort.Open(); //打开串口
                ConnectionStatus = ConnectionStatus.Connected;

                dataPacketProcessService.Start();

                logger.Info("Start->打开串口["+ GlobalVariable.SerialPortName + ","+ GlobalVariable.SerialPortBaudRate + "]");
                ConnectionStatusNotify();

                //发送卡号查询
                byte[] cmdBytes = SendProtocol.EncodeINQ();
                SendCmdData(cmdBytes);
            }
            catch (Exception ex)
            {
                MessageBox.Show("串行端口打开失败！具体原因：" + ex.Message, "提示" );

                ConnectionStatus = ConnectionStatus.Disconnected;
                ConnectionStatusNotify();
                return false;
            }
            return true;
        }

        public bool Stop()
        {
            try
            {
                ConnectionStatus = ConnectionStatus.Disconnected;
                serialPort.Close(); //关闭串口

                dataPacketProcessService.Stop();

                logger.Info("Stop->关闭串口[" + GlobalVariable.SerialPortName + "," + GlobalVariable.SerialPortBaudRate + "]");
                ConnectionStatusNotify();
                
            }
            catch (Exception ex)
            {
                return false;
            }


            return true;
        }

        /// <summary>
        /// 串口数据处理函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDataReceived(Object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //Comm.BytesToRead中为要读入的字节长度
                int len = serialPort.BytesToRead;
                Byte[] readBuffer = new Byte[len];
                serialPort.Read(readBuffer, 0, len); //将数据读入缓存
                //logger.Info("OnDataReceived->" + System.Text.Encoding.Default.GetString(readBuffer));

                dataPacketProcessService.ReadyToProcess(readBuffer);

                PortDataNotify("接收->" + System.Text.Encoding.Default.GetString(readBuffer));
            }
            catch (Exception ex)
            {

            }
        }

        public bool SendCmdData(byte[] data)
        {
            if (data == null || data.Length == 0)
                return false;
            if (!serialPort.IsOpen)
            {
                return false;
            }
            serialPort.Write(data, 0, data.Length);

            PortDataNotify("发送->" + System.Text.Encoding.Default.GetString(data));
            return true;
        }

        public ConnectionStatus GetConnectionStatus()
        {
            return ConnectionStatus;
        }

        public event OnConnectionStatusNotifyEventHandler OnConnectionStatusNotify;

        private void ConnectionStatusNotify()
        {
            if (OnConnectionStatusNotify != null)
            {
                OnConnectionStatusNotify(ConnectionStatus);
            }
        }

        public event OnPortDataNotifyEventHandler OnPortDataNotifyEventHandler;

        private void PortDataNotify(string data)
        {
            if (OnPortDataNotifyEventHandler != null)
            {
                OnPortDataNotifyEventHandler(data);
            }
        }
    }
}
